package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.uqbike.client.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.client.constant.SysConstant;
import com.tbit.uqbike.client.constant.SystemConstant;
import com.tbit.uqbike.client.constant.enums.SourceType;
import com.tbit.uqbike.client.dao.log.UserFaceLogDao;
import com.tbit.uqbike.client.pojo.OssConfig;
import com.tbit.uqbike.client.pojo.User;
import com.tbit.uqbike.client.pojo.newEntity.UserFaceLog;
import com.tbit.uqbike.client.service.CacheService;
import com.tbit.uqbike.client.service.UserFaceLogService;
import com.tbit.uqbike.client.util.FaceUtil;
import com.tbit.uqbike.client.util.SourceUtil;
import com.tbit.uqbike.client.util.aliyun.OssFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @Description:
 * @author: zhoujj
 * @date: 2023/11/8 10:51
 * @Version: 3.8.2
 */
@Slf4j
@Service
public class UserFaceLogServiceImpl implements UserFaceLogService {
    @Autowired
    private UserFaceLogDao userFaceLogDao;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private UserOpLogService userOpLogService;

    /**
     * 一个人脸识别图片的存储策略->人脸识别成功时，保存在数据库三张，失败时两张；同时图片同步oss
     *
     * @param user
     * @param base64Str
     * @param success
     * @param remark
     * @param similarity
     */
    @Override
    public void insertUserFaceLogAndUpdate(User user, String base64Str, Integer success, String remark, Double similarity, String engine) {
        if (base64Str == null || base64Str.isEmpty()) {
            return;
        }
        OssConfig ossConfig = cacheService.getOssConfigFaceLog(user.getAccountId(), SystemConstant.SAVE_FACE_IMG_OSS_BUCKET_NAME);
        // 保留到百分比整数
        similarity = NumberUtil.toDouble(NumberUtil.round(similarity, 2));
        try {
            //base64Str直接转字节流
            InputStream inputStream = FaceUtil.base64ToInputStream(base64Str.contains(",") ? base64Str.split(",")[1] : base64Str);
            String uid = UUID.randomUUID().toString();
            //加一层目录
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            LocalDateTime t = LocalDateTime.now();
            //目录格式faceLog + yyyyMMdd
            String dir = "faceLog" + t.format(formatter);
            String imageId = String.format(dir + "/%s.%d.%d", uid, user.getUserId(), similarity.intValue());
            //imageId = dir + uid;
            //图片上传到OSS
            String url = OssFileUtils.uploadByAliYun(inputStream, ossConfig, imageId, "jpg", OssFileUtils.IMAGE);
            UserFaceLog userFaceLog = new UserFaceLog();
            userFaceLog.setAccountId(user.getAccountId());
            userFaceLog.setUrl(url);
            userFaceLog.setUserId(user.getUserId());
            userFaceLog.setRemark(remark);
            userFaceLog.setSuccess(success);
            //如果不是报错导致的认证失败,都记录similarity相似度
            userFaceLog.setSimilarity(success != SysConstant.USER_FACE_FAIL ? similarity : 0d);
            userFaceLog.setEngine(engine);
            userFaceLog.setSource(transformSourceCode(SourceUtil.getCurrentSource()));
            //userFaceLog保存到local
            userFaceLogDao.insertUserFaceLog(userFaceLog);
            //查询多余的图片
            List<UserFaceLog> userFaceLogs = userFaceLogDao.queryUserFaceLogsByUserId(user.getUserId(), success, success == SysConstant.USER_FACE_SUCCESS ? SysConstant.USER_FACE_SUCCESS_LIMIT : SysConstant.USER_FACE_FAIL_LIMIT);
            for (UserFaceLog faceLog : userFaceLogs) {
                //删除多余的local记录
                userFaceLogDao.deleteUserFaceLogsByFaceId(faceLog.getFaceId());
                //去除oss.url的前缀
                String wholeUrl = faceLog.getUrl();
                int i = wholeUrl.lastIndexOf("/", wholeUrl.lastIndexOf("/") - 1);
                String urlKey = faceLog.getUrl().substring(i + 1);
                //删除OSS的多余的图片
                OssFileUtils.deleteObject(ossConfig, urlKey);
            }

            // 插入用户操作日志
            userOpLogService.insertSingle(UserOpLog.builder()
                    .accountId(user.getAccountId())
                    .opUser(user.getName())
                    .opUserPhone(user.getPhone())
                    .targetUser(user.getName())
                    .targetUserPhone(user.getPhone())
                    .operation("用户账号")
                    .opType("人脸识别")
                    .opPlatform(OperationPlatform.CLIENT.code)
                    .opTime(LocalDateTime.now())
                    .result(SysConstant.USER_FACE_SUCCESS.equals(success))
                    .build());
        } catch (Exception e) {
            log.error("人脸识别图像存储userId:" + user.getUserId() + ";图片处理异常：", e);
        }
    }

    private Integer transformSourceCode(SourceType type) {
        switch (type) {
            case WECHAT:
                return 1;
            case ALIPAY:
                return 2;
            default:
                return -1;
        }
    }
}
